home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\IF.C < prev    next >
C/C++ Source or Header  |  1994-12-28  |  11KB  |  530 lines

  1. /*
  2.  * if.c: handles the IF command for IRCII 
  3.  *
  4.  * Written By Michael Sandrof
  5.  *
  6.  * Copyright(c) 1990, 1991 
  7.  *
  8.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
  9.  */
  10.  
  11. #ifndef lint
  12. static    char    rcsid[] = "@(#)$Id: if.c,v 1.7 1994/07/02 02:32:13 mrg Stab $";
  13. #endif
  14.  
  15. #include "irc.h"
  16. #include "alias.h"
  17. #include "ircaux.h"
  18. #include "window.h"
  19. #include "vars.h"
  20. #include "output.h"
  21.  
  22. extern    char    *arg_numword();
  23. extern    int    word_count();
  24. extern    char    *stristr();
  25. extern    char    *rstristr();
  26.  
  27. int     lastif;
  28.  
  29. /*
  30.  * next_expr finds the next expression delimited by brackets. The type
  31.  * of bracket expected is passed as a parameter. Returns NULL on error.
  32.  */
  33. extern 
  34. char    *
  35. next_expr(args, type)
  36.     char    **args;
  37.     char    type;
  38. {
  39.     char    *ptr,
  40.         *ptr2,
  41.         *ptr3;
  42.  
  43.     if (!*args)
  44.         return NULL;
  45.     ptr2 = *args;
  46.     if (!*ptr2)
  47.         return 0;
  48.     if (*ptr2 != type)
  49.     {
  50.         say("Expression syntax");
  51.         return 0;
  52.     }                            /* { */
  53.     ptr = MatchingBracket(ptr2 + 1, type, (type == '(') ? ')' : '}');
  54.     if (!ptr)
  55.     {
  56.         say("Unmatched '%c'", type);
  57.         return 0;
  58.     }
  59.     *ptr = '\0';
  60.     do
  61.     {
  62.         ptr2++;
  63.     }
  64.     while (isspace(*ptr2));
  65.     ptr3 = ptr+1;
  66.     while (isspace(*ptr3))
  67.         ptr3++;
  68.     *args = ptr3;
  69.     if (*ptr2)
  70.     {
  71.         ptr--;
  72.         while (isspace(*ptr))
  73.             *ptr-- = '\0';
  74.     }
  75.     return ptr2;
  76. }
  77.  
  78. /*ARGSUSED*/
  79. void
  80. ifcmd(command, args, subargs)
  81.     char    *command,
  82.         *args;
  83.     char    *subargs;
  84. {
  85.     char    *exp;
  86.     char    *sub;
  87.     int    flag = 0;
  88.     int    result;
  89.  
  90.     if (!(exp = next_expr(&args, '(')))
  91.     {
  92.         yell("Missing CONDITION in IF");
  93.         return;
  94.     }
  95.     sub = parse_inline(exp, subargs?subargs:empty_string, &flag);
  96.     if (get_int_var(DEBUG_VAR) & DEBUG_EXPANSIONS)
  97.         yell("If expression expands to: (%s)", sub);
  98.     if (!*sub || *sub == '0')
  99.         result = 0;
  100.     else
  101.         result = 1;
  102.     new_free(&sub);
  103.     if (!(exp = next_expr(&args, '{')))
  104.     {
  105.         yell("Missing THEN portion in IF");
  106.         return;
  107.     }
  108.     if (!result && !(exp = next_expr(&args, '{')))
  109.         return;
  110.     parse_line((char *) 0, exp, subargs ? subargs : empty_string, 0, 0);
  111.         return;
  112. }
  113.  
  114. /*ARGSUSED*/
  115. void
  116. whilecmd(command, args, subargs)
  117.     char    *command,
  118.         *args;
  119.     char    *subargs;
  120. {
  121.     char    *exp = (char *) 0,
  122.         *ptr,
  123.         *body = (char *) 0,
  124.         *newexp = (char *) 0;
  125.     int    args_used;    /* this isn't used here, but is passed
  126.                  * to expand_alias() */
  127.  
  128.     if ((ptr = next_expr(&args, '(')) == (char *) 0)
  129.     {
  130.         yell("WHILE: missing boolean expression");
  131.         return;
  132.     }
  133.     malloc_strcpy(&exp, ptr);
  134.     if ((ptr = next_expr(&args, '{')) == (char *) 0)
  135.     {
  136.         say("WHILE: missing expression");
  137.         new_free(&exp);
  138.         return;
  139.     }
  140.     malloc_strcpy(&body, ptr);
  141.     while (1)
  142.     {
  143.         malloc_strcpy(&newexp, exp);
  144.         ptr = parse_inline(newexp, subargs ? subargs : empty_string,
  145.             &args_used);
  146.         if (*ptr && *ptr !='0')
  147.         {
  148.             new_free(&ptr);
  149.             parse_line((char *) 0, body, subargs ?
  150.                 subargs : empty_string, 0, 0);
  151.         }
  152.         else
  153.             break;
  154.     }
  155.     new_free(&newexp);
  156.     new_free(&ptr);
  157.     new_free(&exp);
  158.     new_free(&body);
  159. }
  160.  
  161. void fe();
  162. void foreach();
  163. void forcmd();
  164.  
  165. int    
  166. charcount(string, what)
  167.     char    *string,
  168.         what;
  169. {
  170.     int     x       = 0;
  171.     char    *place  = string-1;
  172.  
  173.     while (place = index(place+1, what))
  174.         x++;
  175.     return x;
  176. }
  177.  
  178. /*
  179.  * How it works -- if There are no parenthesis, it must be a
  180.  * foreach array command.  If there are parenthesis, and there are
  181.  * exactly two commas, it must be a C-like for command, else it must
  182.  * must be an foreach word command
  183.  */
  184. void
  185. foreach_handler(command,args,subargs)
  186.     char    *command,
  187.         *args,
  188.         *subargs;
  189. {
  190.     char    *temp = (char *) 0;
  191.     char    *placeholder;
  192.     char    *temp2 = (char *) 0;
  193.     int     ick=0;
  194.  
  195.     malloc_strcpy(&temp, args);
  196.     placeholder = temp;
  197.     if (*temp == '(')
  198.     {
  199.         if ((temp2 = next_expr(&temp,'(')) == (char *) 0) {
  200.             new_free(&placeholder);
  201.             return;
  202.         }
  203.         if (charcount(temp2,',') == 2)
  204.             forcmd(command,args,subargs);
  205.         else
  206.             fe(command,args,subargs);
  207.     }
  208.     else
  209.         foreach(command,args,subargs);
  210.     new_free(&placeholder);
  211. }
  212.  
  213. /*ARGSUSED*/
  214. void
  215. foreach(command, args, subargs)
  216.     char    *command,
  217.         *args;
  218.     char    *subargs;
  219. {
  220.     char    *struc = (char *) 0,
  221.         *ptr,
  222.         *body = (char *) 0,
  223.         *var = (char *) 0;
  224.     char    **sublist;
  225.     int    total;
  226.     int    i;
  227.     int    slen;
  228.     int    old_display;
  229.  
  230.     if ((ptr = new_next_arg(args, &args)) == (char *) 0)
  231.     {
  232.         yell("FOREACH: missing structure expression");
  233.         return;
  234.     }
  235.     malloc_strcpy(&struc, ptr);
  236.     malloc_strcat(&struc, ".");
  237.     upper(struc);
  238.     if ((var = next_arg(args, &args)) == (char *) 0)
  239.     {
  240.         new_free(&struc);
  241.         yell("FOREACH: missing variable");
  242.         return;
  243.     }
  244.     while (isspace(*args))
  245.         *args++;
  246.     if ((body = next_expr(&args, '{')) == (char *) 0)    /* } */
  247.     {
  248.         new_free(&struc);
  249.         yell("FOREACH: missing statement");
  250.         return;
  251.     }
  252.     sublist=match_alias(struc, &total, VAR_ALIAS);
  253.     slen=strlen(struc);
  254.     old_display=window_display;
  255.     for (i=0;i<total;i++)
  256.     {
  257.         window_display=0;
  258.         add_alias(VAR_ALIAS, var, sublist[i]+slen);
  259.         window_display=old_display;
  260.         parse_line((char *) 0, body, subargs ?
  261.             subargs : empty_string, 0, 0);
  262.         new_free(&sublist[i]);
  263.     }
  264.     new_free(&sublist);
  265.     new_free(&struc);
  266. }
  267.  
  268. /*
  269.  * FE:  Written by Jeremy Nelson (jnelson@iastate.edu)
  270.  *
  271.  * FE: replaces recursion
  272.  *
  273.  * The thing about it is that you can nest variables, as this command calls
  274.  * expand_alias until the list doesnt change.  So you can nest lists in
  275.  * lists, and hopefully that will work.  However, it also makes it 
  276.  * impossible to have $s anywhere in the list.  Maybe ill change that
  277.  * some day.
  278.  */
  279.  
  280. void
  281. fe(command, args, subargs)
  282.     char    *command,
  283.         *args,
  284.         *subargs;
  285. {
  286.     char    *list = (char *) 0,
  287.         *templist = (char *) 0,
  288.         *placeholder,
  289.         *oldlist = (char *) 0,
  290.         *sa,
  291.         *vars,
  292.         *var[255],
  293.         *word = (char *) 0,
  294.         *todo = (char *) 0;
  295.     int     ind, x, y, blah,args_flag;
  296.     int     old_display;
  297.  
  298.     for (x = 0; x <= 255; var[x++] = (char *) 0)
  299.         ;
  300.  
  301.     list = next_expr(&args, '(');    /* ) */
  302.     if (!list)
  303.     {
  304.         yell ("FE: Missing List for /FE");
  305.         return;
  306.     }
  307.  
  308.     sa = subargs ? subargs : " ";
  309.     malloc_strcpy(&templist, list);
  310.     do 
  311.     {
  312.         malloc_strcpy(&oldlist, templist);
  313.         new_free(&templist);
  314.         templist = expand_alias((char *) 0,oldlist,sa,&args_flag, (char **) 0);
  315.     } while (strcmp(templist, oldlist));
  316.  
  317.     new_free(&oldlist);
  318.  
  319.     if (*templist == '\0')
  320.     {
  321.         new_free(&templist);
  322.         return;
  323.     }
  324.  
  325.     vars = args;
  326.     if (!(args = index(args, '{')))        /* } */
  327.     {
  328.         yell ("FE: Missing commands");
  329.         new_free(&templist);
  330.         return;
  331.     }
  332.     *(args-1) = '\0';
  333.     ind = 0;
  334.     while (var[ind++] = next_arg(vars, &vars))
  335.     {
  336.         if (ind == 255)
  337.         {
  338.             yell ("FE: Too many variables");
  339.             new_free(&templist);
  340.             return;
  341.         }
  342.     }
  343.     ind = ind ? ind - 1: 0;
  344.  
  345.     if (!(todo = next_expr(&args, '{')))        /* } { */
  346.     {
  347.         yell ("FE: Missing }");        
  348.         new_free(&templist);
  349.         return;
  350.     }
  351.  
  352.     blah = word_count(templist);
  353.     old_display = window_display;
  354.     placeholder = templist;
  355.     for ( x = 0 ; x < blah ; )
  356.     {
  357.         window_display = 0;
  358.         for ( y = 0 ; y < ind ; y++ )
  359.         {
  360.             word = ((x+y)<blah)
  361.                 ? next_arg(templist, &templist)
  362.                 : (char *) 0;
  363.             add_alias(VAR_ALIAS, var[y], word);
  364.         }
  365.         window_display = old_display;
  366.         x += ind;
  367.         parse_line((char *) 0, todo, 
  368.             subargs?subargs:empty_string, 0, 0);
  369.     }
  370.     window_display = 0;
  371.     for (y=0;y<ind;y++)  {
  372.         delete_alias(VAR_ALIAS,var[y]);
  373.     }
  374.     window_display = old_display;
  375.     new_free(&placeholder);
  376. }
  377.  
  378. /* FOR command..... prototype: 
  379.  *  for (commence,evaluation,iteration)
  380.  * in the same style of C's for, the for loop is just a specific
  381.  * type of WHILE loop.
  382.  *
  383.  * IMPORTANT: Since ircII uses ; as a delimeter between commands,
  384.  * commas were chosen to be the delimiter between expressions,
  385.  * so that semicolons may be used in the expressions (think of this
  386.  * as the reverse as C, where commas seperate commands in expressions,
  387.  * and semicolons end expressions.
  388.  */
  389. /*  I suppose someone could make a case that since the
  390.  *  foreach_handler() routine weeds out any for command that doesnt have
  391.  *  two commans, that checking for those 2 commas is a waste.  I suppose.
  392.  */
  393. void
  394. forcmd(command, args, subargs)
  395.     char    *command;
  396.     char    *args;
  397.     char    *subargs;
  398. {
  399.     char        *working        = (char *) 0;
  400.     char        *commence       = (char *) 0;
  401.     char        *evaluation     = (char *) 0;
  402.     char        *lameeval       = (char *) 0;
  403.     char        *iteration      = (char *) 0;
  404.     char        *sa             = (char *) 0;
  405.     int         argsused        = 0;
  406.     char        *blah           = (char *) 0;
  407.     char        *commands       = (char *) 0;
  408.  
  409.     /* Get the whole () thing */
  410.     if ((working = next_expr(&args, '(')) == (char *) 0)    /* ) */
  411.     {
  412.         yell("FOR: missing closing parenthesis");
  413.         return;
  414.     }
  415.     malloc_strcpy(&commence, working);
  416.  
  417.     /* Find the beginning of the second expression */
  418.     evaluation = index(commence, ',');
  419.     if (!evaluation)
  420.     {
  421.         yell("FOR: no components!");
  422.         new_free(&commence);
  423.         return;
  424.     }
  425.     do 
  426.         *evaluation++ = '\0';
  427.     while (isspace(*evaluation));
  428.  
  429.     /* Find the beginning of the third expression */
  430.     iteration = index(evaluation, ',');
  431.     if (!iteration)
  432.     {
  433.         yell("FOR: Only two components!");
  434.         new_free(&commence);
  435.         return;
  436.     }
  437.     do 
  438.     {
  439.         *iteration++ = '\0';
  440.     }
  441.     while (isspace(*iteration));
  442.  
  443.     working = args;
  444.     while (isspace(*working))
  445.         *working++ = '\0';
  446.  
  447.     if ((working = next_expr(&working, '{')) == (char *) 0)        /* } */
  448.     {
  449.         yell("FOR: badly formed commands");
  450.         new_free(&commence);
  451.         return;
  452.     }
  453.  
  454.     malloc_strcpy(&commands, working);
  455.  
  456.     sa = subargs?subargs:empty_string;
  457.     parse_line((char *) 0, commence, sa, 0, 0);
  458.  
  459.     while (1)
  460.     {
  461.         malloc_strcpy(&lameeval, evaluation);
  462.         blah = parse_inline(lameeval,sa,&argsused);
  463.         if (*blah && *blah != '0')
  464.         {
  465.             new_free(&blah);
  466.             parse_line((char *) 0, commands, sa, 0, 0);
  467.             parse_line((char *) 0, iteration, sa, 0, 0);
  468.         }
  469.         else break;
  470.     }
  471.     new_free(&blah);
  472.     new_free(&lameeval);
  473.     new_free(&commence);
  474.     new_free(&commands);
  475. }
  476.  
  477. /* fec - iterate over a list of characters */
  478.  
  479. extern    void
  480. fec(command, args, subargs)
  481.     char    *command,
  482.     *args,
  483.     *subargs;
  484. {
  485.     char    *pointer;
  486.     char    *list = (char *) 0;
  487.     char    *var = (char *) 0;
  488.     char    booya[2];
  489.     int     args_flag = 0, old_display;
  490.     char    *sa,*todo;
  491.  
  492.     list = next_expr(&args, '(');        /* ) */
  493.     if (list == (char *) 0)
  494.     {
  495.         yell ("FEC: Missing List for /FEC");
  496.         return;
  497.     }
  498.  
  499.     sa = subargs ? subargs : empty_string;
  500.     list = expand_alias((char *) 0,list,sa,&args_flag,(char **) 0);
  501.     pointer = list;
  502.  
  503.     var = next_arg(args, &args);
  504.     args = index(args, '{');        /* } */
  505.  
  506.     if ((todo = next_expr(&args, '{')) == (char *) 0)
  507.     {
  508.         yell ("FE: Missing }");
  509.         return;
  510.     }
  511.  
  512.     booya[1] = '\0';
  513.     old_display = window_display;
  514.  
  515.     while (*pointer)
  516.     {
  517.         window_display = 0;
  518.         booya[0] = *pointer++;
  519.         add_alias(VAR_ALIAS, var, booya);
  520.         window_display = old_display;
  521.         parse_line((char *) 0, todo, 
  522.             subargs?subargs:empty_string, 0, 0);
  523.     }
  524.     window_display = 0;
  525.     delete_alias(VAR_ALIAS,var);
  526.     window_display = old_display;
  527.  
  528.     new_free(&list);
  529. }
  530.